package edu.gatech.mobile.scene.provider.impl;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.BaseColumns;
import edu.gatech.mobile.scene.AppConstants;
import edu.gatech.mobile.scene.AppConstants.RELATIVE_TO_HORIZON;
import edu.gatech.mobile.scene.model.ColorHistogram;
import edu.gatech.mobile.scene.model.LabelInfo;
import edu.gatech.mobile.scene.model.MaskInfo;

public class MaskInfoDBImpl {
	
	private Context mContext;
	private LabelInfoDBImpl labelDB;
	private ColorHistogramDBImpl colorDB;
	
	public MaskInfoDBImpl(Context context){
		mContext=context;
		labelDB = new LabelInfoDBImpl(context);
		colorDB = new ColorHistogramDBImpl(context);
	}
	
	/**
	 * 
	 * @param maskInfo training mask to be inserted
	 * @return the row id of the newly inserted row.
	 */
	public long putMask(MaskInfo maskInfo){
		ContentResolver resolver = mContext.getContentResolver();
		Uri uri = resolver.insert(MaskInfoTable.CONTENT_URI, getQueryValues(maskInfo));
		long id = ContentUris.parseId(uri);
		maskInfo.getHistograms().setMaskId(id);
		colorDB.putHistogram(maskInfo.getHistograms());
		return id; 
	}
	
	
	public void removeMask(MaskInfo maskInfo){
		ContentResolver resolver = mContext.getContentResolver();
		final String where= MaskInfoTable.MASK_NAME + "='"+ maskInfo.getMaskName()+"'";
		resolver.delete(MaskInfoTable.CONTENT_URI, where, null);
	}
	
	public Cursor getAllMasksCursor(){
		ContentResolver resolver = mContext.getContentResolver();
		Cursor cursor =resolver.query(MaskInfoTable.CONTENT_URI, null, null, null, null);
		return cursor;
	}
	
	public List<MaskInfo>getMasks(){
		List<MaskInfo> items = new ArrayList<MaskInfo>();
		ContentResolver resolver = mContext.getContentResolver();
		Cursor cursor =resolver.query(MaskInfoTable.CONTENT_URI, null, null, null, null);
		while (cursor != null && cursor.getCount() > 0 && !cursor.isLast()){
			MaskInfo item = fillFromCursor(cursor);
			items.add(item);
		}
		safelyCloseCursor(cursor);
		return items;
	}
	public List<MaskInfo>getMasksforImage(String origImagename){
		List<MaskInfo> items = new ArrayList<MaskInfo>();
		ContentResolver resolver = mContext.getContentResolver();
		String where = MaskInfoTable.ORIGINAL_IMAGE_NAME + "='"+origImagename+"'";
		Cursor cursor =resolver.query(MaskInfoTable.CONTENT_URI, null, where, null, null);
		
		while (cursor != null && cursor.getCount() > 0 && !cursor.isLast()){
			MaskInfo item = fillFromCursor(cursor);
			items.add(item);
		}
		safelyCloseCursor(cursor);
		return items;
	}
	
	public void removeMasksForImage(String origImageName){
		ContentResolver resolver = mContext.getContentResolver();
		final String where= MaskInfoTable.ORIGINAL_IMAGE_NAME + "='"+origImageName+"'";
		int maskIdDelted = resolver.delete(MaskInfoTable.CONTENT_URI, where, null);
		//TODO remove color histogram for all the histograms.
	}
	
	
	public MaskInfo getMaskWithID(int id){
		ContentResolver resolver = mContext.getContentResolver();
		String where = BaseColumns._ID + " = "+id;
		Cursor cursor =resolver.query(MaskInfoTable.CONTENT_URI, null, where, null, null);
		MaskInfo mask = fillFromCursor(cursor);
		safelyCloseCursor(cursor);
		return mask;
	}
	
	
	public int getMaskCountWithHorizon(RELATIVE_TO_HORIZON horizonInfo){
		ContentResolver resolver = mContext.getContentResolver();
		String	where= MaskInfoTable.RELATIVE_TO_HORIZON+" = "+horizonInfo.ordinal();
		Cursor cursor =resolver.query(MaskInfoTable.CONTENT_URI, null, where, null, null);
		int count = cursor.getCount();
		safelyCloseCursor(cursor);
		return count;
	}
	
	public int getMaskCountWithHorizonAndImage(RELATIVE_TO_HORIZON horizonInfo, String imagePath){
		ContentResolver resolver = mContext.getContentResolver();
		String	where= MaskInfoTable.RELATIVE_TO_HORIZON+" = "+horizonInfo.ordinal() + " and "
					+ MaskInfoTable.ORIGINAL_IMAGE_NAME + "='" + imagePath + "'" ;
		Cursor cursor =resolver.query(MaskInfoTable.CONTENT_URI, null, where, null, null);
		int count = cursor.getCount();
		safelyCloseCursor(cursor);
		return count;
	}
	
	
	private ContentValues getQueryValues(MaskInfo maskInfo){
		Long time;
		if((time=maskInfo.getTime()) == null){
			time = System.currentTimeMillis();
		}
		
		ContentValues values = new ContentValues();
		values.put(MaskInfoTable.ORIGINAL_IMAGE_NAME, maskInfo.getOrigImageName());
		values.put(MaskInfoTable.MASK_NAME, maskInfo.getMaskName());
		values.put(MaskInfoTable.LABEL_NAME, maskInfo.getLabelInfo().getLabelName());
		values.put(MaskInfoTable.TIME_POSTED, time);
		values.put(MaskInfoTable.PIXEL_LOC_X, maskInfo.getPixelLocX());
		values.put(MaskInfoTable.PIXEL_LOC_Y, maskInfo.getPixelLocY());
		values.put(MaskInfoTable.RELATIVE_TO_HORIZON, maskInfo.getHorizonPosition().ordinal());
		return values;
	}
	
	private MaskInfo fillFromCursor(Cursor cursor){
		cursor.moveToNext();
		MaskInfo maskInfo = new MaskInfo();
		maskInfo.setTime(cursor.getLong(cursor.getColumnIndex(MaskInfoTable.TIME_POSTED)));
		maskInfo.setId(cursor.getLong(cursor.getColumnIndex(BaseColumns._ID)));
		maskInfo.setMaskName(cursor.getString(cursor.getColumnIndex(MaskInfoTable.MASK_NAME)));
		maskInfo.setOrigImageName(cursor.getString(cursor.getColumnIndex(MaskInfoTable.ORIGINAL_IMAGE_NAME)));
		LabelInfo labelInfo = labelDB.getLabelByName(cursor.getString(cursor.getColumnIndex(MaskInfoTable.LABEL_NAME)));
		maskInfo.setLabelInfo(labelInfo);
		
		maskInfo.setPixelLocX(cursor.getInt(cursor.getColumnIndex(MaskInfoTable.PIXEL_LOC_X)));
		maskInfo.setPixelLocY(cursor.getInt(cursor.getColumnIndex(MaskInfoTable.PIXEL_LOC_Y)));
		
		int horizonOrdinalVal = cursor.getInt(cursor.getColumnIndex(MaskInfoTable.RELATIVE_TO_HORIZON));
		maskInfo.setHorizonPosition(AppConstants.RELATIVE_TO_HORIZON.values()[horizonOrdinalVal]);
		
		ColorHistogram histogram = colorDB.getHistogramForMask(maskInfo.getId());
		maskInfo.setHistograms(histogram);
		
		return maskInfo;
	}
	
	
	
	private void safelyCloseCursor(Cursor cur) {
		if(cur != null && cur.isClosed() == false)
			cur.close();
	}
	
	
}
